"""
Text processing tools for FastMCP
"""

from fastmcp import FastMCP
from typing import List, Optional
import re
import json


class TextTools:
    """Text processing tools for FastMCP."""

    def __init__(self, mcp: FastMCP):
        self.mcp = mcp

    def register(self):
        """Register all text tools with FastMCP."""
        self.mcp.tool(
            name="count_words",
            description="Count the number of words, characters, and lines in text",
            tags={"text", "analysis", "public"},
        )(self.count_words)

        self.mcp.tool(
            name="extract_emails",
            description="Extract email addresses from text",
            tags={"text", "extraction", "email", "public"},
        )(self.extract_emails)

        self.mcp.tool(
            name="extract_urls",
            description="Extract URLs from text",
            tags={"text", "extraction", "url", "public"},
        )(self.extract_urls)

        self.mcp.tool(
            name="clean_text",
            description="Clean and normalize text by removing extra whitespace, converting case, etc.",
            tags={"text", "cleaning", "normalization", "public"},
        )(self.clean_text)

        self.mcp.tool(
            name="find_and_replace",
            description="Find and replace text using regular expressions or simple string matching",
            tags={"text", "replace", "regex", "public"},
        )(self.find_and_replace)

        self.mcp.tool(
            name="generate_slug",
            description="Generate a URL-friendly slug from text",
            tags={"text", "slug", "url", "public"},
        )(self.generate_slug)

    @staticmethod
    def count_words(text: str) -> dict:
        """Count words, characters, lines, and paragraphs in the given text."""
        if not text:
            return {
                "words": 0,
                "characters": 0,
                "characters_no_spaces": 0,
                "lines": 0,
                "paragraphs": 0,
            }

        # Count words (split by whitespace)
        words = len(text.split())

        # Count characters
        characters = len(text)
        characters_no_spaces = len(text.replace(" ", ""))

        # Count lines
        lines = len(text.split("\n"))

        # Count paragraphs (separated by double newlines)
        paragraphs = len([p for p in text.split("\n\n") if p.strip()])

        return {
            "words": words,
            "characters": characters,
            "characters_no_spaces": characters_no_spaces,
            "lines": lines,
            "paragraphs": paragraphs,
        }

    @staticmethod
    def extract_emails(text: str) -> dict:
        """Extract all email addresses from the given text."""
        email_pattern = r"\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b"
        emails = re.findall(email_pattern, text)

        return {
            "emails_found": len(emails),
            "emails": list(set(emails)),  # Remove duplicates
        }

    @staticmethod
    def extract_urls(text: str) -> dict:
        """Extract all URLs from the given text."""
        url_pattern = r"http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*\\(\\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+"
        urls = re.findall(url_pattern, text)

        return {"urls_found": len(urls), "urls": list(set(urls))}  # Remove duplicates

    @staticmethod
    def clean_text(
        text: str,
        remove_extra_whitespace: bool = True,
        convert_case: Optional[str] = None,  # "upper", "lower", "title"
        remove_punctuation: bool = False,
        remove_numbers: bool = False,
    ) -> dict:
        """Clean and normalize text based on specified options."""
        original_text = text
        cleaned_text = text

        # Remove extra whitespace
        if remove_extra_whitespace:
            cleaned_text = re.sub(r"\s+", " ", cleaned_text.strip())

        # Convert case
        if convert_case == "upper":
            cleaned_text = cleaned_text.upper()
        elif convert_case == "lower":
            cleaned_text = cleaned_text.lower()
        elif convert_case == "title":
            cleaned_text = cleaned_text.title()

        # Remove punctuation
        if remove_punctuation:
            cleaned_text = re.sub(r"[^\w\s]", "", cleaned_text)

        # Remove numbers
        if remove_numbers:
            cleaned_text = re.sub(r"\d+", "", cleaned_text)

        return {
            "original_text": original_text,
            "cleaned_text": cleaned_text,
            "operations_applied": {
                "remove_extra_whitespace": remove_extra_whitespace,
                "convert_case": convert_case,
                "remove_punctuation": remove_punctuation,
                "remove_numbers": remove_numbers,
            },
        }

    @staticmethod
    def find_and_replace(
        text: str,
        find: str,
        replace: str,
        use_regex: bool = False,
        case_sensitive: bool = True,
        replace_all: bool = True,
    ) -> dict:
        """Find and replace text in the input string."""
        original_text = text
        flags = 0 if case_sensitive else re.IGNORECASE

        try:
            if use_regex:
                if replace_all:
                    new_text = re.sub(find, replace, text, flags=flags)
                    count = len(re.findall(find, text, flags=flags))
                else:
                    new_text = re.sub(find, replace, text, count=1, flags=flags)
                    count = 1 if re.search(find, text, flags=flags) else 0
            else:
                # Simple string replacement
                if not case_sensitive:
                    # Case-insensitive string replacement is more complex
                    pattern = re.escape(find)
                    if replace_all:
                        new_text = re.sub(pattern, replace, text, flags=re.IGNORECASE)
                        count = len(re.findall(pattern, text, flags=re.IGNORECASE))
                    else:
                        new_text = re.sub(
                            pattern, replace, text, count=1, flags=re.IGNORECASE
                        )
                        count = (
                            1 if re.search(pattern, text, flags=re.IGNORECASE) else 0
                        )
                else:
                    if replace_all:
                        count = text.count(find)
                        new_text = text.replace(find, replace)
                    else:
                        count = 1 if find in text else 0
                        new_text = text.replace(find, replace, 1)

            return {
                "original_text": original_text,
                "new_text": new_text,
                "replacements_made": count,
                "find_pattern": find,
                "replace_with": replace,
                "options": {
                    "use_regex": use_regex,
                    "case_sensitive": case_sensitive,
                    "replace_all": replace_all,
                },
            }

        except re.error as e:
            return {
                "error": f"Regular expression error: {str(e)}",
                "original_text": original_text,
            }

    @staticmethod
    def generate_slug(text: str, max_length: int = 50) -> dict:
        """Generate a URL-friendly slug from the input text."""
        # Convert to lowercase
        slug = text.lower()

        # Replace spaces and special characters with hyphens
        slug = re.sub(r"[^\w\s-]", "", slug)
        slug = re.sub(r"[-\s]+", "-", slug)

        # Remove leading/trailing hyphens
        slug = slug.strip("-")

        # Truncate if too long
        if len(slug) > max_length:
            slug = slug[:max_length].rstrip("-")

        return {
            "original_text": text,
            "slug": slug,
            "length": len(slug),
            "max_length": max_length,
        }
